package org.xtremeobjects.domain.person;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.hibernate.annotations.GenericGenerator;
import org.xtremeobjects.anotations.JavaBean;
import org.xtremeobjects.anotations.Label;
import org.xtremeobjects.domain.party.Party;

@Entity
@JavaBean
@Label("Contato ${self.description}")
public class ContactDetail implements Serializable {

	@Id
	@GeneratedValue(generator="system-uuid")
	@GenericGenerator(name="system-uuid", strategy = "uuid")
	private String id;
	private String description;

	@ManyToOne
	private Party party;

	@OneToMany(mappedBy="contactDetail", cascade=CascadeType.ALL,targetEntity=Phone.class)
	private List<Phone> phones;

	@OneToMany(mappedBy="contactDetail", cascade=CascadeType.ALL,targetEntity=Address.class)
	private List<Address> addresses;

	@OneToMany(mappedBy="contactDetail", cascade=CascadeType.ALL,targetEntity=Email.class)
	private List<Email> emails;


	private ContactDetail()
	{
	}

	public ContactDetail(Party party, String description) {
		this.party = party;
		setDescription(description);

	}

	public ContactDetail addAddress(String description, String line1, String line2, String city, String state, String zipcode, String country) {
		getAddressesModifiable().add(
				new Address(this, description, line1, line2, city, state, zipcode, country)
				);
		return this;
	}

	public ContactDetail addEmail(String description, String email) {
		getEmailsModifiable().add(
				new Email(this, description, email)
				);
		return this;
	}


	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	protected List<Phone> getPhonesModifiable() {
		if(phones == null)
			phones = new ArrayList<Phone>();
		return phones;
	}

	/**
	 * Returns an unmodifiable list of phones
	 * @return
	 */
	public List<Phone> getPhones() {
		return Collections.unmodifiableList(getPhonesModifiable());
	}

	public Phone getPhone(String description) {
		for (Phone phone : getPhonesModifiable()) {
			if(phone.getDescription().equals(description))
				return phone;
		}
		throw new RuntimeException("Phone " + description + " not found");
	}

	public ContactDetail addPhone(String description, String number) {
		getPhonesModifiable().add(new Phone(this, description, number));
		return this;
	}

	protected List<Address> getAddressesModifiable() {
		if(addresses == null)
			addresses = new ArrayList<Address>();
		return addresses;
	}

	public List<Address> getAddresses() {
		return Collections.unmodifiableList(getAddressesModifiable());
	}

	public Address getAddress(String description) {
		for (Address address : getAddressesModifiable()) {
			if( address.getDescription().equals(description))
				return address;
		}
		throw new RuntimeException("Address " + description + " not found");
	}


	public Email getEmail(String description) {
		for (Email email : getEmails()) {
			if(email.getDescription().equals(description))
				return email;
		}
		throw new RuntimeException("Email " + description + " not found");
	}

	/**
	 * @return the emails
	 */
	public List<Email> getEmails() {
		return Collections.unmodifiableList(getEmailsModifiable());
	}

	protected List<Email> getEmailsModifiable() {
		if(emails == null)
			emails = new ArrayList<Email>();
		return emails;
	}


}
